home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume24 / mced / part01 next >
Encoding:
Text File  |  1991-10-26  |  53.4 KB  |  2,289 lines

  1. Newsgroups: comp.sources.misc
  2. From: aknight@ourgang.Prime.COM (Andy Knight x445)
  3. Subject:  v24i022:  mced - C-shell history command line editor v2.0, Part01/01
  4. Message-ID: <1991Oct26.220453.5036@sparky.imd.sterling.com>
  5. X-Md4-Signature: edcea2f63c01367b55b9cba54dcf9620
  6. Date: Sat, 26 Oct 1991 22:04:53 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: aknight@ourgang.Prime.COM (Andy Knight x445)
  10. Posting-number: Volume 24, Issue 22
  11. Archive-name: mced/part01
  12. Environment: UNIX, C-shell
  13. Supersedes: mced: Volume 21, Issue 94
  14.  
  15. Here is mced2.0, which now has vi-mode. There are some minor 
  16. bug fixes and enhancements as well, which should make it somewhat 
  17. faster and more portable. (Vi-mode is also more elaborate than 
  18. emacs-mode, including . p <nn>function and undo. :-))
  19.  
  20.  ------
  21. McEd is a utility which allows you to browse, edit and execute
  22. commands from your C-shell history list. It is not a shell itself, 
  23. but it executes the commands in your current shell as if you had 
  24. typed them in.  The editing functions are based on gnuemacs or vi, 
  25. see the Makefile to select either one.
  26.  
  27.  ------
  28. Andy Knight,           SunOS_humor% man reboot | sed -n '/Avoid/,/fire/p'
  29. Computervision Corp.     >>>>  -n   Avoid the sync(1). It can be used if
  30. aknight@ourgang.prime.com  >>>>     a disk or the processor is on fire.
  31. ------
  32. #! /bin/sh
  33. # This is a shell archive, meaning:
  34. # 1. Remove everything above the #! /bin/sh line.
  35. # 2. Save the resulting text in a file.
  36. # 3. Execute the file with /bin/sh (not csh) to create the files:
  37. #    README
  38. #    Makefile
  39. #    mced.1
  40. #    Bugs
  41. #    main.c
  42. #    vi_edit.c
  43. #    emacs_edit.c
  44. #    getch.c
  45. #    getch.h
  46. #    config.h
  47. # This archive created: Fri Oct 18 14:38:05 1991
  48. export PATH; PATH=/bin:$PATH
  49. echo shar: extracting "'README'" '(2131 characters)'
  50. if test -f 'README'
  51. then
  52.     echo shar: will not over-write existing file "'README'"
  53. else
  54. sed 's/^X//' << \SHAR_EOF > 'README'
  55. XDESCRIPTION:
  56. X
  57. XMcEd is a utility which allows you to browse, edit and execute
  58. Xcommands from your C-shell history list. It is not a shell itself, 
  59. Xbut it executes the commands in your current shell as if you had 
  60. Xtyped them in.  The editing functions are based on gnuemacs or vi,
  61. Xsee the Makefile to select either one.
  62. X    
  63. X
  64. XUSAGE:
  65. X
  66. XAfter making the executable, Put the following
  67. Xsomewhat lengthly :-) alias for "=" in your .cshrc:
  68. Xalias = "history -h 50 >\! /tmp/eh$$;mced \!*;
  69. Xsource -h /tmp/ec$$;source /tmp/ec$$;/bin/rm /tmp/ec$$"
  70. X(one line)
  71. X
  72. X``='' now copies the commands in your history list into memory
  73. Xand allows you to browse and edit, <CR> executes the command.
  74. XSee the man page for details on editing.
  75. X
  76. XIf possible, avoid using SYSV curses. If you have no choice,
  77. Xyou must put #define SYSVcurses somewhere near the top of config.h.
  78. X
  79. X
  80. XI hope that you will find mced useful, - let me know if you
  81. Xhave any problems, suggestions etc..
  82. X
  83. X-Andy [Mc]Knight
  84. X
  85. X
  86. X/*
  87. X * This software is Copyright (c) 1991 by Andy Knight
  88. X * (getch.c and getch.h Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe)
  89. X *
  90. X * Permission is hereby granted to copy, distribute or otherwise
  91. X * use any part of this package as long as you do not try to make
  92. X * money from it or pretend that you wrote it.  This copyright
  93. X * notice must be maintained in any copy made.
  94. X *
  95. X * Use of this software constitutes acceptance for use in an AS IS
  96. X * condition. There are NO warranties with regard to this software.
  97. X * In no event shall the author be liable for any damages whatsoever
  98. X * arising out of or in connection with the use or performance of this
  99. X * software.  Any use of this software is at the user's own risk.
  100. X *
  101. X * If you make modifications to this software that you feel
  102. X * increases it usefulness for the rest of the community, please
  103. X * email the changes, enhancements, bug fixes as well as any and
  104. X * all ideas to me. This software is going to be maintained and
  105. X * enhanced as deemed necessary by the community.
  106. X *
  107. X * " ... Freely you have recieved, freely give"  <Matthew 10:8>
  108. X *
  109. X *              Andy Knight
  110. X *              aknight@ourgang.prime.com
  111. X */
  112. SHAR_EOF
  113. if test 2131 -ne "`wc -c < 'README'`"
  114. then
  115.     echo shar: error transmitting "'README'" '(should have been 2131 characters)'
  116. fi
  117. fi # end of overwriting check
  118. echo shar: extracting "'Makefile'" '(1011 characters)'
  119. if test -f 'Makefile'
  120. then
  121.     echo shar: will not over-write existing file "'Makefile'"
  122. else
  123. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  124. X#
  125. X#    Makefile for mced
  126. X#
  127. X#    To install this utility do the following:
  128. X#           1) Select vi or emacs mode by uncommenting one of the
  129. X#              OBJECTS lines below.
  130. X#        2) Fill in the BINDIR and MANDIR variables.
  131. X#        3) Type "make install" on the command line.
  132. X#        4) Type "make clean" on the command line to clean up after install.
  133. X#
  134. X#
  135. X#
  136. X# definitions for EMACS EDIT mode:
  137. X#OBJECTS = main.o emacs_edit.o getch.o
  138. X#
  139. X# definitions for VI EDIT mode:
  140. XOBJECTS = main.o vi_edit.o getch.o
  141. X#
  142. X# Where to stick the executable on install
  143. XBINDIR=/usr/local/bin
  144. X#
  145. X# Where to stick the man page on install
  146. XMANDIR=/usr/local/man/man1
  147. X#
  148. XLDFLAGS = -lcurses -ltermcap
  149. X#
  150. XCFLAGS = -O     ## do not use optimizer on SunOS 4.0.3S ##
  151. X
  152. Xmced : $(OBJECTS)
  153. X    $(CC) $(TARGET_ARCH) $(CFLAGS) $(OBJECTS) -o $@ $(LDFLAGS)
  154. X
  155. Xman : mced.1
  156. X    cat mced.1 | nroff -man > mced.man
  157. X
  158. Xinstall : mced
  159. X    install -s -c mced $(BINDIR)
  160. X    install -m 644 mced.1 $(MANDIR)/mced.1
  161. X    ln -s $(MANDIR)/mced.1 $(MANDIR)/=.1
  162. X
  163. Xclean : 
  164. X    rm -f mced core $(OBJECTS)
  165. X
  166. SHAR_EOF
  167. if test 1011 -ne "`wc -c < 'Makefile'`"
  168. then
  169.     echo shar: error transmitting "'Makefile'" '(should have been 1011 characters)'
  170. fi
  171. fi # end of overwriting check
  172. echo shar: extracting "'mced.1'" '(4179 characters)'
  173. if test -f 'mced.1'
  174. then
  175.     echo shar: will not over-write existing file "'mced.1'"
  176. else
  177. sed 's/^X//' << \SHAR_EOF > 'mced.1'
  178. X.TH McEd 1 "1 October 1991"
  179. X.SH NAME
  180. Xmced \- McKnight's unix history Command line Editor
  181. X.SH SYNOPSIS
  182. X.B "= [string]"
  183. X.SH DESCRIPTION
  184. X.I "mced"
  185. Xis a utility giving the C-shell added history flexibility with 
  186. Xbrowsing and editing functions for commands in the history list.
  187. X.I "mced"
  188. Xis driven by an alias which should be defined as follows: 
  189. X.nf
  190. X.sp
  191. Xalias = "history -h 50 >\\! /tmp/eh$$;mced \\!*;source -h /tmp/ec$$;\
  192. Xsource /tmp/ec$$;/bin/rm /tmp/ec$$"
  193. X.SH
  194. X``='' now copies the commands in your history list into memory
  195. Xand positions you at the most recent command, or ``= <string>''
  196. Xpositions you at the first command that begins with <string>.
  197. XThe command is now edited emacs OR vi style, and executed by a <CR>,
  198. XCTRL-U and CTRL-W are used to cancel and delete just as usual.
  199. XShort commands are filtered out of the history list, the
  200. Xminimum length is set with MIN_CMD_LEN, defined in config.h.
  201. XConsecutive duplicate commands are filtered out as well.
  202. XIf you use tcsh, ksh, bash etc. you will probably not have much use for 
  203. Xmced, as these shells have similar history editing built-in.
  204. X
  205. X.SH MOVING AROUND IN THE HISTORY LIST
  206. XThe up and down arrow keys index you through the history list,
  207. Xif <string> is used on the command line, CTRL-R and CTRL-S (emacs mode)
  208. Xor n (vi mode) search for the next occurrence. 
  209. X
  210. X.SH 
  211. X
  212. X.SH CURSOR MOVEMENT
  213. XThe standard emacs control and escape characters (or vi cursor motion 
  214. Xcharacters) (CTRL-A, CTRL-B, CTRL-E, CTRL-F, ESC-B, ESC-F (^,$,w,b,h,l))
  215. Xand arrow keys are used to move around on the command line.
  216. XESC-M moves to the middle of the command line.
  217. X.SH EMACS EDITING SUMMARY
  218. X.I "mced"
  219. X.RS +.6i
  220. X.nf
  221. X.ta 2.5i
  222. X.sp
  223. XEditing functions
  224. X.sp
  225. Xbeginning of line    CTRL-A
  226. Xbackward char        CTRL-B
  227. Xdelete char        CTRL-D
  228. Xend of line        CTRL-E
  229. Xforward char        CTRL-F
  230. Xkill to end of line    CTRL-K
  231. Xredraw command        CTRL-L
  232. Xdown history        CTRL-N
  233. Xup history        CTRL-P
  234. Xsearch backward        CTRL-R
  235. Xsearch forward        CTRL-S
  236. Xtranspose characters    CTRL-T
  237. Xbackward delete char    Delete
  238. Xbackward delete word    ESC-Delete, CTRL-W
  239. Xbackward word        ESC-B
  240. Xchange case character    ESC-C **
  241. Xdelete word forward    ESC-D
  242. Xforward word        ESC-F
  243. Xdowncase command    ESC-L **
  244. Xmiddle cursor        ESC-M **
  245. Xupcase command        ESC-U **
  246. Xexecute command        <CR>
  247. Xquit            CTRL-U, CTRL-C
  248. X
  249. X** Function behaves differently than in gnuemacs
  250. X
  251. X--------------------------------------------------------------
  252. X
  253. X.SH VI EDITING SUMMARY
  254. X.I "mced"
  255. X.RS +.6i
  256. X.nf
  257. X.ta 2.5i
  258. X.sp
  259. XEditing functions
  260. X.sp
  261. Xbeginning of line    ^
  262. Xend of line        $
  263. Xmiddle of line        ESC-M **
  264. Xbackward char        h
  265. Xforward char        l
  266. Xbackward word        b
  267. Xforward word        w
  268. Xdown history        j
  269. Xup history        k
  270. Xsearch backward        n
  271. Xredraw command        CTRL-L
  272. Xinsert at current pos    i
  273. Xinsert at beginning    I
  274. Xappend            a
  275. Xappend at end        A
  276. Xdelete char        x
  277. Xdelete word forward    dw,dW
  278. Xkill to end of line    D
  279. Xput last delete        p,P
  280. Xredo last change    .
  281. Xundo last change    u
  282. Xbackward delete word    CTRL-W **
  283. Xchange case character    ~
  284. Xchange word        cw,cW
  285. Xchange to end of line    C
  286. Xreplace one character    r
  287. Xreplace forward        R
  288. Xdowncase command    ESC-L **
  289. Xupcase command        ESC-U **
  290. Xexecute command        <CR> *
  291. Xquit            CTRL-U, CTRL-C, dd
  292. X
  293. X<nn> "function" may be used to repeat the function <nn> times.
  294. X
  295. X* Will also execute command in insert mode
  296. X** Function is not in standard vi screen editor
  297. X
  298. X--------------------------------------------------------------
  299. X
  300. XLines may be joined together by doing a delete at the end
  301. Xof the command line in emacs mode, or "J" in vi mode.
  302. X
  303. XKey mappings for sun R function keys around the arrow keys
  304. Xare defined to do some cursor movement and other functions,
  305. Xsee source for details ({emacs,vi}_edit.c)
  306. X
  307. XThere is currently no undo function (in emacs mode).
  308. X
  309. XThe window for the command always occupies the last two lines
  310. Xon your screen, the command length cannot go beyond this. 
  311. X(Note: if you use SysV curses the command will occupy the first
  312. Xtwo lines on the screen)
  313. X
  314. X.SH AUTHOR
  315. XAndy [Mc]Knight, Computervision;
  316. Xaknight@ourgang.prime.com
  317. X.sp
  318. Xgetch.c and getch.h were snatched
  319. Xfrom scan, written by Patrick J. Wolfe
  320. X.SH "THANKS TO"
  321. XMichael R. Haley, Tize Ma, Kevin Cosgrove and Brian Murray
  322. Xfor their help reviewing and beta testing mced2.0.
  323. X.SH SEE ALSO
  324. X.BR tcsh(1),
  325. X.BR gnuemacs(1),
  326. X.BR vi(1),
  327. X.BR csh_builtins(1)
  328. SHAR_EOF
  329. if test 4179 -ne "`wc -c < 'mced.1'`"
  330. then
  331.     echo shar: error transmitting "'mced.1'" '(should have been 4179 characters)'
  332. fi
  333. fi # end of overwriting check
  334. echo shar: extracting "'Bugs'" '(542 characters)'
  335. if test -f 'Bugs'
  336. then
  337.     echo shar: will not over-write existing file "'Bugs'"
  338. else
  339. sed 's/^X//' << \SHAR_EOF > 'Bugs'
  340. X1 -     foreach loops will not execute from mced.
  341. X    (!! immediately after will execute the edited foreach)
  342. X
  343. X2 -    Everything after # in a command string is ignored, 
  344. X    put a backslash before # so source will not treat 
  345. X    it as the start of a comment.
  346. X
  347. X3 -    mced cannot be stopped (CTRL-Z) and then restarted,
  348. X    the command sequence in the "=" alias is broken when
  349. X    the process is stopped.
  350. X
  351. X4 -    In a Sunview cmdtool the screen goes blank when mced
  352. X    is invoked, after the command is executed the screen
  353. X    is redrawn without the executed command showing.
  354. X
  355. SHAR_EOF
  356. if test 542 -ne "`wc -c < 'Bugs'`"
  357. then
  358.     echo shar: error transmitting "'Bugs'" '(should have been 542 characters)'
  359. fi
  360. fi # end of overwriting check
  361. echo shar: extracting "'main.c'" '(8124 characters)'
  362. if test -f 'main.c'
  363. then
  364.     echo shar: will not over-write existing file "'main.c'"
  365. else
  366. sed 's/^X//' << \SHAR_EOF > 'main.c'
  367. X/*
  368. X * This software is Copyright (c) 1991 by Andy Knight
  369. X *
  370. X * Permission is hereby granted to copy, distribute or otherwise
  371. X * use any part of this package as long as you do not try to make
  372. X * money from it or pretend that you wrote it.  This copyright
  373. X * notice must be maintained in any copy made.
  374. X *
  375. X * Use of this software constitutes acceptance for use in an AS IS
  376. X * condition. There are NO warranties with regard to this software.
  377. X * In no event shall the author be liable for any damages whatsoever
  378. X * arising out of or in connection with the use or performance of this
  379. X * software.  Any use of this software is at the user's own risk.
  380. X *
  381. X * If you make modifications to this software that you feel
  382. X * increases it usefulness for the rest of the community, please
  383. X * email the changes, enhancements, bug fixes as well as any and
  384. X * all ideas to me. This software is going to be maintained and
  385. X * enhanced as deemed necessary by the community.
  386. X * 
  387. X * " ... Freely you have recieved, freely give"  <Matthew 10:8> 
  388. X *
  389. X *              Andy Knight
  390. X *              aknight@ourgang.prime.com
  391. X */
  392. X
  393. X#include "config.h"
  394. X
  395. X
  396. Xchar            buff[BUFSIZE];
  397. X
  398. Xchar            hfile[20], cfile[20];
  399. Xchar            vern[] = "#";
  400. Xchar            spc[] = " ";
  401. Xchar            prompt[] = PROMPT;
  402. Xchar           *hist[MAX_H_READ], cstr[MAX_CH], sstr[30];
  403. Xint             edit_mode, x_pos, savex_pos, xend, cur_cmd, last_hline, xbeg;
  404. Xint             fd, index_cmd();
  405. XFILE           *fptr;
  406. XSIGTYPE         die_curses(), die_normal();
  407. XWINDOW         *win;
  408. Xvoid            my_wmove(), eat_white(), add_hline(), cmd_to_win(), win_to_cmd();
  409. Xvoid            my_waddstr(), my_winsch(), my_wdelch(), case_lower(), case_upper();
  410. Xvoid            edit_line(), exit();
  411. X
  412. X#ifdef SYSVcurses
  413. Xstruct termio   tio, tin;
  414. X#else
  415. Xstruct tchars   tco, tcn;
  416. X#endif
  417. X
  418. X
  419. Xmain(argc, argv)
  420. X    int             argc;
  421. X    char           *argv[];
  422. X{
  423. X    register        i, j, bytes_read;
  424. X    int             last_length, pid;
  425. X
  426. X    signal(SIGINT, die_normal);    /* die cleanly */
  427. X/*
  428. X * get the shell process id (pid) to match $$ in the = alias
  429. X */
  430. X
  431. X    pid = getppid();
  432. X    sprintf(hfile, "/tmp/eh%d", pid);
  433. X    sprintf(cfile, "/tmp/ec%d", pid);
  434. X    xbeg = strlen(prompt);
  435. X/*
  436. X * open the history file
  437. X */
  438. X    fd = open(hfile, 0);
  439. X    if (fd == (int) -1)
  440. X    {
  441. X    perror(hfile);    /* Note: DO NOT ATTEMPT TO STUFF THIS ALIAS, see README */
  442. X    fprintf(stderr, "To execute mced use \"=\" with the following alias:\n");
  443. X    fprintf(stderr, "alias = \"history -h 50 >\\! /tmp/eh$$;mced \\!*;");
  444. X    fprintf(stderr, "source -h /tmp/ec$$;source /tmp/ec$$;/bin/rm /tmp/ec$$\"\n");
  445. X    die_normal();
  446. X    }
  447. X    else
  448. X    {
  449. X    bytes_read = read(fd, buff, BUFSIZE);
  450. X    if (bytes_read == -1)
  451. X    {
  452. X        perror(hfile);
  453. X        die_normal();
  454. X    }
  455. X    if (bytes_read == BUFSIZE)
  456. X        printf("Warning: BUFSIZE is too small, see config.h\n");
  457. X    }
  458. X    last_length = last_hline = j = 0;
  459. X    for (i = 0; i < bytes_read; i++)
  460. X    {
  461. X    if (buff[i] == '\n')
  462. X    {
  463. X        if (i - j >= MIN_CMD_LEN && buff[j] != '=')
  464. X        {
  465. X        hist[last_hline] = &buff[j];
  466. X        buff[i] = '\0';
  467. X        /*** Remove redundant consecutive history lines ***/
  468. X        if ((i - j) == last_length 
  469. X            && strcmp(&buff[j], hist[last_hline - 1]) == 0)
  470. X            --last_hline;
  471. X        last_length = i - j;
  472. X        ++last_hline;
  473. X        }
  474. X        j = i + 1;
  475. X    }
  476. X    }
  477. X
  478. X    --last_hline;
  479. X    cur_cmd = last_hline;
  480. X
  481. X/*
  482. X * check for existence of history before going on
  483. X */
  484. X    if (last_hline < 0)
  485. X    {
  486. X    fprintf(stderr, "No valid history\n");
  487. X    die_normal();
  488. X    }
  489. X
  490. X/*
  491. X * copy search string from command line
  492. X */
  493. X    if (argc > 1)
  494. X    {
  495. X    strcpy(sstr, argv[1]);
  496. X    if (argc > 2)
  497. X    {
  498. X        for (i = 3; i <= argc; i++)
  499. X        {
  500. X        strcat(sstr, spc);
  501. X        strcat(sstr, argv[i - 1]);
  502. X        }
  503. X    }
  504. X    cur_cmd = index_cmd(cur_cmd, -1);
  505. X    }
  506. X    strcpy(cstr, hist[cur_cmd]);
  507. X/*
  508. X * edit command and execute
  509. X */
  510. X    edit_cmd();
  511. X
  512. X/*
  513. X * close and delete history temp file
  514. X */
  515. X    close(fd);
  516. X    unlink(hfile);
  517. X
  518. X/*
  519. X * open file and write command to it
  520. X */
  521. X    if ((fptr = fopen(cfile, "w")) == NULL)
  522. X    {
  523. X        perror(cfile);
  524. X        exit(0);
  525. X    }
  526. X    fprintf(fptr, "%s\n%s\n", vern, cstr);
  527. X    fclose(fptr);
  528. X    printf("\n");
  529. X}
  530. X
  531. X
  532. Xint 
  533. Xindex_cmd(tcur_cmd, direc)
  534. X    int             tcur_cmd, direc;
  535. X{
  536. X    register        i, slen;
  537. X    slen = strlen(sstr);
  538. X    for (i = 0; i <= last_hline; i++)
  539. X    {
  540. X    if (tcur_cmd < 0)
  541. X        tcur_cmd = last_hline;
  542. X    if (tcur_cmd > last_hline)
  543. X        tcur_cmd = 0;
  544. X    if (strncmp(hist[tcur_cmd], sstr, slen) == 0)
  545. X        return (tcur_cmd);
  546. X    tcur_cmd += direc;
  547. X    }
  548. X    return (cur_cmd);
  549. X}
  550. X
  551. X
  552. XSIGTYPE 
  553. Xdie_normal()
  554. X{
  555. X    signal(SIGINT, SIG_IGN);
  556. X    signal(SIGINT, die_normal);
  557. X/*
  558. X * close and delete history temp file
  559. X */
  560. X    close(fd);
  561. X    unlink(hfile);
  562. X
  563. X    if ((fptr = fopen(cfile, "w")) == NULL)
  564. X    {
  565. X        perror(cfile);
  566. X        exit(0);
  567. X    }
  568. X    fprintf(fptr, "%s\n", vern);
  569. X    fclose(fptr);
  570. X    exit(0);
  571. X}
  572. X
  573. X
  574. Xvoid 
  575. Xadd_hline()            /* add next hist line on delete at EOL */
  576. X{
  577. X    if (cur_cmd < last_hline)
  578. X    {
  579. X    ++cur_cmd;
  580. X    savex_pos = x_pos;
  581. X    my_waddstr(hist[cur_cmd]);
  582. X    x_pos = savex_pos;
  583. X    my_wmove(x_pos);
  584. X    }
  585. X    else
  586. X    beep();
  587. X}
  588. X
  589. X
  590. Xvoid 
  591. Xmy_wmove(i)
  592. X    int             i;
  593. X{
  594. X    int             which_line;
  595. X    which_line = ((i < COLS) ? 0 : 1);
  596. X    wmove(win, which_line, (i - which_line * COLS));
  597. X}
  598. X
  599. X
  600. Xvoid 
  601. Xmy_winsch(in_char)
  602. X    int             in_char;
  603. X{
  604. X    int             wrap_char;
  605. X    if ((xend + 1) >= (COLS * 2))
  606. X    {
  607. X    beep();
  608. X    }
  609. X    else if (xend > (COLS - 1) && x_pos < COLS)    /* wraparound */
  610. X    {
  611. X    ++xend;
  612. X    wmove(win, 0, COLS - 1);
  613. X    wrap_char = winch(win);
  614. X    wmove(win, 1, 0);
  615. X    winsch(win, wrap_char);
  616. X    my_wmove(x_pos);
  617. X    winsch(win, in_char);
  618. X    my_wmove(++x_pos);
  619. X    }
  620. X    else
  621. X    {
  622. X    ++xend;
  623. X    winsch(win, in_char);
  624. X    my_wmove(++x_pos);
  625. X    }
  626. X}
  627. X
  628. X
  629. Xvoid 
  630. Xmy_wdelch()
  631. X{
  632. X    int             wrap_char;
  633. X    --xend;
  634. X    if (xend >= COLS && x_pos < COLS)    /* wraparound */
  635. X    {
  636. X    wmove(win, 1, 0);
  637. X    wrap_char = winch(win);
  638. X    wdelch(win);
  639. X    my_wmove(x_pos);
  640. X    wdelch(win);
  641. X    wmove(win, 0, COLS - 1);
  642. X    winsch(win, wrap_char);
  643. X    my_wmove(x_pos);
  644. X    }
  645. X    else
  646. X    {
  647. X    wdelch(win);
  648. X    }
  649. X}
  650. X
  651. X
  652. Xvoid 
  653. Xmy_waddstr(strng)
  654. X    char            strng[];
  655. X{
  656. X    register        i, len;
  657. X    len = strlen(strng);
  658. X    for (i = 0; i < len; i++)
  659. X    {
  660. X    my_winsch((int) strng[i]);
  661. X    }
  662. X}
  663. X
  664. X
  665. Xvoid 
  666. Xcmd_to_win()            /* write prompt and command to window */
  667. X{
  668. X    my_wmove(0);
  669. X    wclear(win);
  670. X    waddstr(win, prompt);
  671. X    xend = x_pos = xbeg;
  672. X    my_waddstr(cstr);
  673. X}
  674. X
  675. X
  676. Xvoid 
  677. Xwin_to_cmd()            /* get the edited line from the window */
  678. X{
  679. X    int             i;
  680. X    my_wmove(xbeg);
  681. X    for (i = 0; i <= (xend - xbeg); i++)
  682. X    {
  683. X    my_wmove(xbeg + i);
  684. X    cstr[i] = winch(win);
  685. X    }
  686. X    cstr[xend - xbeg] = '\0';
  687. X}
  688. X
  689. X
  690. Xvoid 
  691. Xcase_upper()
  692. X{
  693. X    int             i;
  694. X    for (i = 0; i <= (xend - xbeg); i++)
  695. X    {
  696. X    if (islower(cstr[i]))
  697. X        cstr[i] = toupper(cstr[i]);
  698. X    }
  699. X}
  700. X
  701. X
  702. Xvoid 
  703. Xcase_lower()
  704. X{
  705. X    int             i;
  706. X    for (i = 0; i <= (xend - xbeg); i++)
  707. X    {
  708. X    if (isupper(cstr[i]))
  709. X        cstr[i] = tolower(cstr[i]);
  710. X    }
  711. X}
  712. X
  713. X
  714. XSIGTYPE 
  715. Xdie_curses()            /* interrupt signal */
  716. X{
  717. X    signal(SIGINT, SIG_IGN);
  718. X    signal(SIGINT, die_curses);
  719. X#ifdef SYSVcurses
  720. X    if (ioctl(0, TCSETA, &tio) != 0)
  721. X    perror("ioctl");
  722. X#else
  723. X    if (ioctl(0, TIOCSETC, &tco) != 0)
  724. X    perror("ioctl");
  725. X#endif
  726. X    NOCBREAKF();
  727. X    echo();
  728. X    endwin();
  729. X/*
  730. X * close and delete history temp file
  731. X */
  732. X    close(fd);
  733. X    unlink(hfile);
  734. X
  735. X    if ((fptr = fopen(cfile, "w")) == NULL)
  736. X    {
  737. X        perror(cfile);
  738. X        exit(0);
  739. X    }
  740. X    fprintf(fptr, "%s\n", vern);
  741. X    fclose(fptr);
  742. X    printf("\n");
  743. X    exit(0);
  744. X}
  745. X
  746. X
  747. Xvoid 
  748. Xeat_white(direc, destruc)    /* eat up initial whitespace */
  749. X    int             direc, destruc;
  750. X{
  751. X    int             lim;
  752. X    if (direc == -1)
  753. X    lim = xbeg;
  754. X    else
  755. X    lim = xend;
  756. X    if (destruc == NO)
  757. X    {
  758. X    for (; isspace(winch(win));)
  759. X    {
  760. X        if (x_pos != lim)
  761. X        {
  762. X        x_pos += direc;
  763. X        my_wmove(x_pos);
  764. X        }
  765. X        else
  766. X        return;
  767. X    }
  768. X    return;
  769. X    }
  770. X    else            /* actually delete */
  771. X    {
  772. X    for (; isspace(winch(win));)
  773. X    {
  774. X        if (x_pos != lim)
  775. X        {
  776. X        my_wdelch();
  777. X        x_pos += direc;
  778. X        my_wmove(x_pos);
  779. X        if (!(isspace(winch(win))) && direc == 1)
  780. X            my_wmove(--x_pos);
  781. X        }
  782. X        else
  783. X        return;
  784. X    }
  785. X    return;
  786. X    }
  787. X}
  788. SHAR_EOF
  789. if test 8124 -ne "`wc -c < 'main.c'`"
  790. then
  791.     echo shar: error transmitting "'main.c'" '(should have been 8124 characters)'
  792. fi
  793. fi # end of overwriting check
  794. echo shar: extracting "'vi_edit.c'" '(15455 characters)'
  795. if test -f 'vi_edit.c'
  796. then
  797.     echo shar: will not over-write existing file "'vi_edit.c'"
  798. else
  799. sed 's/^X//' << \SHAR_EOF > 'vi_edit.c'
  800. X/*
  801. X * This software is Copyright (c) 1991 by Andy Knight
  802. X *
  803. X * Permission is hereby granted to copy, distribute or otherwise
  804. X * use any part of this package as long as you do not try to make
  805. X * money from it or pretend that you wrote it.  This copyright
  806. X * notice must be maintained in any copy made.
  807. X *
  808. X * Use of this software constitutes acceptance for use in an AS IS
  809. X * condition. There are NO warranties with regard to this software.
  810. X * In no event shall the author be liable for any damages whatsoever
  811. X * arising out of or in connection with the use or performance of this
  812. X * software.  Any use of this software is at the user's own risk.
  813. X *
  814. X * If you make modifications to this software that you feel
  815. X * increases it usefulness for the rest of the community, please
  816. X * email the changes, enhancements, bug fixes as well as any and
  817. X * all ideas to me. This software is going to be maintained and
  818. X * enhanced as deemed necessary by the community.
  819. X * 
  820. X * " ... Freely you have recieved, freely give"  <Matthew 10:8> 
  821. X *
  822. X *        Andy Knight
  823. X *        aknight@ourgang.prime.com
  824. X */
  825. X
  826. X#include "config.h"
  827. X
  828. X
  829. Xextern char    *hist[], cstr[];
  830. Xextern int      xbeg, cur_cmd, last_hline, pwolfe_getch();
  831. Xextern int      edit_mode, x_pos, savex_pos, xend;
  832. X
  833. Xextern void     my_wmove(), add_hline(), cmd_to_win(), win_to_cmd();
  834. Xextern void     my_winsch(), my_waddstr(), case_upper();
  835. Xextern void     my_wdelch(), case_lower(), eat_white();
  836. Xextern SIGTYPE  die_curses(), die_normal();
  837. Xextern WINDOW  *win;
  838. X
  839. X#ifdef SYSVcurses
  840. Xextern struct termio tio, tin;
  841. X#else
  842. Xextern struct tchars tco, tcn;
  843. X#endif
  844. X
  845. X
  846. Xedit_cmd()
  847. X{
  848. X    int             stop_it, p_init, xins_strt, edch, i, j, tmp_cmd;
  849. X    int             dot_mode, dot_iterations, n_iterations, n_times, indx;
  850. X    char            tch, dot_cmd;
  851. X    char            save_ins[MAX_W_SAVED + 1], save_del[MAX_W_SAVED + 1];
  852. X    fprintf(stdout, "\n");
  853. X    if (initscr() == ERR)
  854. X    {
  855. X    fprintf(stderr, "Curses won't initialize - help!\n");
  856. X    die_normal();
  857. X    }
  858. X    signal(SIGINT, die_curses);    /* die cleanly */
  859. X    CBREAKF();
  860. X    noecho();
  861. X#ifdef SYSVcurses
  862. X    win = newwin(2, COLS, 0, 0);
  863. X#else
  864. X    clearok(curscr, FALSE);    /* SYSV curses clears it anyway ;-( */
  865. X    win = newwin(2, COLS, LINES - 2, 0);
  866. X#endif
  867. X
  868. X    cmd_to_win();
  869. X    my_wmove(--x_pos);
  870. X    wrefresh(win);
  871. X    savex_pos = x_pos;
  872. X
  873. X#ifdef SYSVcurses        /* disable STOP/START (CTRL-S) */
  874. X    if (ioctl(0, TCGETA, &tio) != 0)
  875. X    perror("ioctl");
  876. X    tin = tio;
  877. X    tin.c_iflag &= ~IXON;
  878. X    if (ioctl(0, TCSETA, &tin) != 0)
  879. X    perror("ioctl");
  880. X#else
  881. X    if (ioctl(0, TIOCGETC, &tco) != 0)
  882. X    perror("ioctl");
  883. X    tcn = tco;
  884. X    tcn.t_stopc = -1;
  885. X    if (ioctl(0, TIOCSETC, &tcn) != 0)
  886. X    perror("ioctl");
  887. X#endif
  888. X    edit_mode = VI_NINS_MODE;
  889. X    dot_iterations = 1;
  890. X    dot_cmd = NO;
  891. X    n_times = indx = 0;
  892. X    p_init = NO;
  893. X    for (; (edch = pwolfe_getch(win)) != '\n';)
  894. X    {
  895. X    if ((edch == 'u' || edch == 'U') && edit_mode == VI_NINS_MODE)
  896. X    {
  897. X        cmd_to_win();
  898. X        x_pos = savex_pos;
  899. X        my_wmove(x_pos);
  900. X        wrefresh(win);
  901. X        continue;
  902. X    }
  903. X    if (edit_mode == VI_NINS_MODE && (edch == 'a' || edch == 'A'
  904. X         || edch == 'i' || edch == 'I' || edch == 'p' || edch == 'P'
  905. X         || edch == '.' || edch == 'x' || edch == 'd' || edch == 'D'
  906. X         || edch == 'c' || edch == 'C' || edch == 'r' || edch == 'R'
  907. X         || edch == '\~' || edch == 'X' || edch == ControlW 
  908. X         || edch == Sun_R1))
  909. X    {
  910. X        savex_pos = x_pos;
  911. X        win_to_cmd();    /* for undo function */
  912. X        my_wmove(x_pos);
  913. X    }
  914. X    if (edit_mode == VI_NINS_MODE)
  915. X    {
  916. X        if (edch == 'c')
  917. X        {
  918. X        indx = 0;
  919. X        xins_strt = x_pos;
  920. X        edit_mode = VI_c_MODE;
  921. X        continue;
  922. X        }
  923. X        else if (edch == 'd')
  924. X        {
  925. X        edit_mode = VI_d_MODE;
  926. X        continue;
  927. X        }
  928. X        else if (edch == 'r')
  929. X        {
  930. X        edit_mode = VI_r_MODE;
  931. X        continue;
  932. X        }
  933. X        else if (edch == 'R')
  934. X        {
  935. X        indx = 0;
  936. X        xins_strt = x_pos;
  937. X        dot_mode = VI_NINS_MODE;
  938. X        dot_cmd = 'R';
  939. X        edit_mode = VI_R_MODE;
  940. X        continue;
  941. X        }
  942. X    }
  943. X
  944. X    if (isdigit(edch) && edit_mode == VI_NINS_MODE)
  945. X    {
  946. X        if (n_times != 0)
  947. X        n_times *= 10;
  948. X        n_times += edch - '0';
  949. X        continue;
  950. X    }
  951. X
  952. X    if (n_times != 0)
  953. X    {
  954. X        n_iterations = n_times;
  955. X        n_times = 0;
  956. X    }
  957. X    else
  958. X        n_iterations = 1;
  959. X
  960. X    if (edch == '\.' && edit_mode == VI_NINS_MODE)
  961. X    {
  962. X        if (dot_cmd != NO)
  963. X        {
  964. X        edch = dot_cmd;
  965. X        edit_mode = dot_mode;
  966. X        n_iterations = dot_iterations;
  967. X        if (edch == 'i' || edch == 'a')
  968. X        {
  969. X            if (edch == 'a')
  970. X            my_wmove(++x_pos);
  971. X            my_waddstr(save_ins);
  972. X            my_wmove(--x_pos);
  973. X            n_iterations = 0;
  974. X        }
  975. X        else if (edch == 'R')
  976. X        {
  977. X            for (i = 0; i < indx && x_pos >= xbeg && x_pos < xend; i++)
  978. X            my_wdelch();
  979. X            my_waddstr(save_ins);
  980. X            my_wmove(--x_pos);
  981. X            n_iterations = 0;
  982. X        }
  983. X        else if (edit_mode == VI_c_MODE)
  984. X        {
  985. X            my_waddstr(save_ins);
  986. X            n_iterations = 1;
  987. X            edit_mode = VI_c_MODE;
  988. X            dot_mode = NO_BEG_INS;
  989. X        }
  990. X        }
  991. X        else
  992. X        beep();
  993. X    }
  994. X
  995. X    if (edit_mode == VI_INS_MODE)
  996. X    {
  997. X        if (edch == ControlU)
  998. X        {
  999. X        wclear(win);
  1000. X        wrefresh(win);
  1001. X        die_curses();
  1002. X        }
  1003. X        else if (edch == Escape)
  1004. X        {
  1005. X        edit_mode = VI_NINS_MODE;
  1006. X        if (x_pos > xbeg)
  1007. X            my_wmove(--x_pos);
  1008. X        }
  1009. X        else if (edch == ControlW || edch == Sun_R1)
  1010. X        {
  1011. X        if (x_pos > xbeg)
  1012. X        {
  1013. X            my_wmove(--x_pos);
  1014. X            eat_white(-1, YES);
  1015. X            for (; !(isspace(winch(win))) && (x_pos >= xins_strt);)
  1016. X            {
  1017. X            my_wdelch();
  1018. X            if (x_pos == xbeg)
  1019. X                break;
  1020. X            else
  1021. X                my_wmove(--x_pos);
  1022. X            }
  1023. X            if (x_pos > xbeg && x_pos < xend - 1)
  1024. X            my_wmove(++x_pos);
  1025. X        }
  1026. X        else
  1027. X            beep();
  1028. X        }
  1029. X        else if (edch == Delete)
  1030. X        {
  1031. X        if (x_pos > xbeg && x_pos > xins_strt)
  1032. X        {
  1033. X            my_wmove(--x_pos);
  1034. X            my_wdelch();
  1035. X        }
  1036. X        else
  1037. X            beep();
  1038. X        }
  1039. X        else if (isprint(edch))
  1040. X        {
  1041. X        my_winsch(edch);
  1042. X        if (indx < MAX_W_SAVED)
  1043. X        {
  1044. X            save_ins[indx] = edch;
  1045. X            save_ins[++indx] = '\0';
  1046. X        }
  1047. X        }
  1048. X        else
  1049. X        beep();
  1050. X    }
  1051. X    else if (edit_mode == VI_R_MODE)
  1052. X    {
  1053. X        if (edch == Escape)
  1054. X        {
  1055. X        if (x_pos > xbeg)
  1056. X            my_wmove(--x_pos);
  1057. X        if (x_pos > xend - 1)
  1058. X            xend = x_pos + 1;
  1059. X        edit_mode = VI_NINS_MODE;
  1060. X        }
  1061. X        else if (edch == ControlU)
  1062. X        {
  1063. X        wclear(win);
  1064. X        wrefresh(win);
  1065. X        die_curses();
  1066. X        }
  1067. X        else if (edch == Delete)
  1068. X        {
  1069. X        if (x_pos > xbeg && x_pos > xins_strt)
  1070. X        {
  1071. X            my_winsch(' ');
  1072. X            x_pos -= 2;
  1073. X            my_wmove(x_pos);
  1074. X            my_wdelch();
  1075. X            save_ins[--indx] = ' ';
  1076. X        }
  1077. X        else
  1078. X            beep();
  1079. X        }
  1080. X        else if (isprint(edch))
  1081. X        {
  1082. X        my_wdelch();
  1083. X        my_winsch(edch);
  1084. X        if (indx < MAX_W_SAVED)
  1085. X        {
  1086. X            save_ins[indx] = edch;
  1087. X            save_ins[++indx] = '\0';
  1088. X        }
  1089. X        }
  1090. X        else
  1091. X        beep();
  1092. X    }
  1093. X    else
  1094. X    {
  1095. X        stop_it = NO;
  1096. X        for (j = 0; j < n_iterations && edch != Escape; j++)
  1097. X        {
  1098. X        if (edit_mode == VI_d_MODE || edit_mode == VI_c_MODE)
  1099. X        {
  1100. X            if (edch == 'w' || edch == 'W')    /* delete or change word */
  1101. X            {
  1102. X            if (x_pos < xend)
  1103. X            {
  1104. X                if (!(isalnum(winch(win))) && winch(win) != '_'
  1105. X                && edch == 'w')
  1106. X                {
  1107. X                if (x_pos < xend)
  1108. X                {
  1109. X                    p_init = YES;
  1110. X                    if (MAX_W_SAVED > 1)
  1111. X                    {
  1112. X                    save_del[0] = winch(win);
  1113. X                    save_del[1] = '\0';
  1114. X                    }
  1115. X                    my_wdelch();
  1116. X                    i = 1;
  1117. X                }
  1118. X                }
  1119. X                else
  1120. X                {
  1121. X                for (i = 0; (( edch == 'w' && (isalnum(winch(win))) 
  1122. X                    || edch == 'W') 
  1123. X                    && !(isspace(winch(win))) 
  1124. X                    || winch(win) == '_') 
  1125. X                    && (x_pos < xend);)
  1126. X                {
  1127. X                    if (i < MAX_W_SAVED)
  1128. X                    save_del[i] = winch(win);
  1129. X                    my_wdelch();
  1130. X                    ++i;
  1131. X                }
  1132. X                save_del[MIN(i, MAX_W_SAVED)] = '\0';
  1133. X                p_init = YES;
  1134. X                }
  1135. X                if (winch(win) == ' ' && x_pos <= xend - 1
  1136. X                && edit_mode != VI_c_MODE)
  1137. X                {
  1138. X                my_wdelch();
  1139. X                if (i < MAX_W_SAVED)
  1140. X                {
  1141. X                    save_del[i] = ' ';
  1142. X                    save_del[MIN((i + 1), MAX_W_SAVED)] = '\0';
  1143. X                }
  1144. X                }
  1145. X            }
  1146. X            else
  1147. X                beep();
  1148. X            if (x_pos == xend && edit_mode != VI_c_MODE)
  1149. X                my_wmove(--x_pos);
  1150. X            if (edit_mode == VI_d_MODE)
  1151. X            {
  1152. X                dot_cmd = edch;
  1153. X                dot_iterations = n_iterations;
  1154. X                dot_mode = VI_d_MODE;
  1155. X            }
  1156. X            if (edit_mode == VI_c_MODE)
  1157. X            {
  1158. X                if (dot_mode != NO_BEG_INS)
  1159. X                edit_mode = VI_INS_MODE;
  1160. X                else
  1161. X                {
  1162. X                edit_mode = VI_NINS_MODE;
  1163. X                my_wmove(--x_pos);
  1164. X                }
  1165. X                dot_cmd = edch;
  1166. X                dot_iterations = 1;
  1167. X                dot_mode = VI_c_MODE;
  1168. X            }
  1169. X            else if (j >= n_iterations - 1)
  1170. X                edit_mode = VI_NINS_MODE;
  1171. X            }
  1172. X            else if (edch == 'd' && edit_mode != VI_c_MODE)
  1173. X            {
  1174. X            wclear(win);
  1175. X            wrefresh(win);
  1176. X            die_curses();
  1177. X            break;
  1178. X            }
  1179. X            else
  1180. X            {
  1181. X            edit_mode = VI_NINS_MODE;
  1182. X            beep();
  1183. X            }
  1184. X
  1185. X        }
  1186. X        else if (edit_mode == VI_r_MODE)
  1187. X        {
  1188. X            if (isprint(edch))
  1189. X            {
  1190. X            dot_mode = VI_r_MODE;
  1191. X            dot_cmd = edch;
  1192. X            my_wdelch();
  1193. X            my_winsch(edch);
  1194. X            my_wmove(--x_pos);
  1195. X            }
  1196. X            else
  1197. X            beep();
  1198. X            edit_mode = VI_NINS_MODE;
  1199. X        }
  1200. X        else
  1201. X        {
  1202. X            switch (edch)
  1203. X            {
  1204. X            case 'I':
  1205. X            dot_cmd = NO;
  1206. X            x_pos = xbeg;
  1207. X            xins_strt = x_pos;
  1208. X            my_wmove(x_pos);
  1209. X            edit_mode = VI_INS_MODE;
  1210. X            break;
  1211. X            case 'i':
  1212. X            indx = 0;
  1213. X            dot_cmd = 'i';
  1214. X            dot_iterations = 1;
  1215. X            dot_mode = VI_NINS_MODE;
  1216. X            xins_strt = x_pos;
  1217. X            edit_mode = VI_INS_MODE;
  1218. X            break;
  1219. X            case 'A':
  1220. X            dot_cmd = NO;
  1221. X            if (x_pos < xend)
  1222. X            {
  1223. X                x_pos = xend;
  1224. X                xins_strt = x_pos;
  1225. X                my_wmove(x_pos);
  1226. X            }
  1227. X            edit_mode = VI_INS_MODE;
  1228. X            break;
  1229. X            case 'a':
  1230. X            indx = 0;
  1231. X            dot_cmd = 'a';
  1232. X            dot_iterations = 1;
  1233. X            dot_mode = VI_NINS_MODE;
  1234. X            if (x_pos < xend)
  1235. X                my_wmove(++x_pos);
  1236. X            xins_strt = x_pos;
  1237. X            edit_mode = VI_INS_MODE;
  1238. X            break;
  1239. X            case ControlU:
  1240. X            case Sun_R3:
  1241. X            wclear(win);
  1242. X            wrefresh(win);
  1243. X            die_curses();
  1244. X            break;
  1245. X            case ControlW:    /* Delete backwards to next space */
  1246. X            case Sun_R1:
  1247. X            dot_cmd = ControlW;
  1248. X            dot_iterations = n_iterations;
  1249. X            dot_mode = VI_NINS_MODE;
  1250. X            if (x_pos > xbeg)
  1251. X            {
  1252. X                if (x_pos != xend - 1)
  1253. X                my_wmove(--x_pos);
  1254. X                eat_white(-1, YES);
  1255. X                for (; !(isspace(winch(win))) && (x_pos >= xbeg);)
  1256. X                {
  1257. X                my_wdelch();
  1258. X                if (x_pos == xbeg)
  1259. X                    break;
  1260. X                else
  1261. X                    my_wmove(--x_pos);
  1262. X                }
  1263. X                if (x_pos > xbeg && x_pos < xend - 1)
  1264. X                my_wmove(++x_pos);
  1265. X            }
  1266. X            else
  1267. X                beep();
  1268. X            break;
  1269. X            case 'b':    /* move back to beginning of previous word */
  1270. X            case 'B':
  1271. X            case Sun_R4:
  1272. X            if (x_pos > xbeg)
  1273. X            {
  1274. X                my_wmove(--x_pos);
  1275. X                eat_white(-1, NO);
  1276. X                for (; !(isspace(winch(win))) && (x_pos > xbeg);)
  1277. X                {
  1278. X                my_wmove(--x_pos);
  1279. X                }
  1280. X                if (x_pos > xbeg)
  1281. X                my_wmove(++x_pos);
  1282. X            }
  1283. X            else
  1284. X                beep();
  1285. X            break;
  1286. X            case 'w':    /* move forward to beginning of next word */
  1287. X            case 'W':
  1288. X            case Sun_R6:
  1289. X            if (x_pos < xend - 1)
  1290. X            {
  1291. X                eat_white(1, NO);
  1292. X                for (; !(isspace(winch(win))) && (x_pos < xend - 1);)
  1293. X                {
  1294. X                my_wmove(++x_pos);
  1295. X                }
  1296. X                if (x_pos < xend - 1)
  1297. X                my_wmove(++x_pos);
  1298. X            }
  1299. X            else
  1300. X                beep();
  1301. X            break;
  1302. X            case ControlL:    /* redraw win */
  1303. X            savex_pos = x_pos;
  1304. X            win_to_cmd();
  1305. X            wclear(win);
  1306. X            wrefresh(win);
  1307. X            cmd_to_win();
  1308. X            x_pos = savex_pos;
  1309. X            my_wmove(x_pos);
  1310. X            break;
  1311. X            case BackSpace:
  1312. X            case KEY_LEFT:
  1313. X            case KEY_BACKSPACE:
  1314. X            case 'h':
  1315. X            case Sun_R10:
  1316. X            if (x_pos > xbeg)
  1317. X                my_wmove(--x_pos);
  1318. X            else
  1319. X                beep();
  1320. X            break;
  1321. X            case EscapeM:    /* move cursor to middle */
  1322. X            case Sun_R11:
  1323. X            x_pos = xbeg + (xend - xbeg) / 2;
  1324. X            my_wmove(x_pos);
  1325. X            break;
  1326. X            case KEY_RIGHT:
  1327. X            case 'l':
  1328. X            case ' ':
  1329. X            case Sun_R12:
  1330. X            if (x_pos < xend - 1)
  1331. X                my_wmove(++x_pos);
  1332. X            else
  1333. X                beep();
  1334. X            break;
  1335. X            case KEY_UP:    /* move upward in history list */
  1336. X            case 'k':
  1337. X            case Sun_R8:
  1338. X            if (cur_cmd > 0)
  1339. X            {
  1340. X                --cur_cmd;
  1341. X                strcpy(cstr, hist[cur_cmd]);
  1342. X                wclear(win);
  1343. X                cmd_to_win();
  1344. X                my_wmove(--x_pos);
  1345. X            }
  1346. X            else
  1347. X                beep();
  1348. X            break;
  1349. X            case KEY_DOWN:    /* move downward in history list */
  1350. X            case 'j':
  1351. X            case Sun_R14:
  1352. X            if (cur_cmd < last_hline)
  1353. X            {
  1354. X                ++cur_cmd;
  1355. X                strcpy(cstr, hist[cur_cmd]);
  1356. X                wclear(win);
  1357. X                cmd_to_win();
  1358. X                my_wmove(--x_pos);
  1359. X            }
  1360. X            else
  1361. X                beep();
  1362. X            break;
  1363. X            case 'n':    /* search history list backwards */
  1364. X            if ((tmp_cmd = index_cmd(cur_cmd - 1, -1)) != cur_cmd)
  1365. X            {
  1366. X                cur_cmd = tmp_cmd;
  1367. X                strcpy(cstr, hist[cur_cmd]);
  1368. X                wclear(win);
  1369. X                cmd_to_win();
  1370. X                my_wmove(--x_pos);
  1371. X            }
  1372. X            else
  1373. X                beep();
  1374. X            break;
  1375. X            case '\^':
  1376. X            case Sun_R7:
  1377. X            my_wmove(xbeg);
  1378. X            x_pos = xbeg;
  1379. X            break;
  1380. X            case '\$':
  1381. X            case Sun_R13:
  1382. X            case Sun_R9:
  1383. X            x_pos = xend - 1;
  1384. X            my_wmove(x_pos);
  1385. X            break;
  1386. X            case 'D':    /* delete to end of line */
  1387. X            if (x_pos < xend)
  1388. X            {
  1389. X                p_init = YES;
  1390. X                dot_cmd = NO;
  1391. X                for (i = 0; (xend - x_pos) > 0; i++)
  1392. X                {
  1393. X                if (i < MAX_W_SAVED)
  1394. X                {
  1395. X                    save_del[i] = winch(win);
  1396. X                    save_del[MIN((i + 1), MAX_W_SAVED)] = '\0';
  1397. X                }
  1398. X                my_wdelch();
  1399. X                }
  1400. X                if (x_pos == xend)
  1401. X                my_wmove(--x_pos);
  1402. X            }
  1403. X            else
  1404. X                beep();
  1405. X            break;
  1406. X            case 'C':    /* delete to end of line and insert */
  1407. X            if (x_pos < xend)
  1408. X            {
  1409. X                dot_cmd = NO;
  1410. X                xins_strt = x_pos;
  1411. X                for (i = xend; i > x_pos; i--)
  1412. X                {
  1413. X                my_wdelch();
  1414. X                }
  1415. X                edit_mode = VI_INS_MODE;
  1416. X            }
  1417. X            else
  1418. X                beep();
  1419. X            break;
  1420. X            case 'J':
  1421. X            x_pos = xend;
  1422. X            my_wmove(x_pos);
  1423. X            my_winsch(' ');
  1424. X            add_hline();
  1425. X            break;
  1426. X            case 'p':
  1427. X            case 'P':
  1428. X            if (p_init == YES)
  1429. X            {
  1430. X                if (edch == 'p')
  1431. X                my_wmove(++x_pos);
  1432. X                my_waddstr(save_del);
  1433. X                my_wmove(--x_pos);
  1434. X            }
  1435. X            else
  1436. X                beep();
  1437. X            break;
  1438. X            case 'x':    /* delete current character */
  1439. X            dot_cmd = 'x';
  1440. X            dot_iterations = n_iterations;
  1441. X            dot_mode = VI_NINS_MODE;
  1442. X            p_init = YES;
  1443. X            if (j < MAX_W_SAVED)
  1444. X            {
  1445. X                save_del[j] = winch(win);
  1446. X                save_del[MIN((j + 1), MAX_W_SAVED)] = '\0';
  1447. X            }
  1448. X            if (x_pos == xend - 1 && stop_it == NO)
  1449. X            {
  1450. X                if (j <= n_iterations - 1)
  1451. X                stop_it = YES;
  1452. X                my_wdelch();
  1453. X                my_wmove(--x_pos);
  1454. X            }
  1455. X            else if (x_pos != xend - 1)
  1456. X            {
  1457. X                if (x_pos >= xbeg)
  1458. X                {
  1459. X                my_wdelch();
  1460. X                }
  1461. X                else
  1462. X                beep();
  1463. X            }
  1464. X            break;
  1465. X            case 'X':    /* delete character before cursor */
  1466. X            dot_cmd = 'X';
  1467. X            dot_iterations = n_iterations;
  1468. X            dot_mode = VI_NINS_MODE;
  1469. X            if (x_pos > xbeg)
  1470. X            {
  1471. X                my_wmove(--x_pos);
  1472. X                p_init = YES;
  1473. X                if ((n_iterations - j - 1) < MAX_W_SAVED)
  1474. X                {
  1475. X                save_del[n_iterations - j - 1] = winch(win);
  1476. X                save_del[MIN(n_iterations, MAX_W_SAVED)] = '\0';
  1477. X                }
  1478. X                my_wdelch();
  1479. X            }
  1480. X            else
  1481. X                beep();
  1482. X            break;
  1483. X            case EscapeL:    /* lower case whole command */
  1484. X            case Sun_R2:
  1485. X            savex_pos = x_pos;
  1486. X            win_to_cmd();
  1487. X            case_lower();
  1488. X            cmd_to_win();
  1489. X            x_pos = savex_pos;
  1490. X            my_wmove(x_pos);
  1491. X            break;
  1492. X            case EscapeU:    /* upper case whole command */
  1493. X            savex_pos = x_pos;
  1494. X            win_to_cmd();
  1495. X            case_upper();
  1496. X            cmd_to_win();
  1497. X            x_pos = savex_pos;
  1498. X            my_wmove(x_pos);
  1499. X            break;
  1500. X            case '\~':    /* toggle case of current character */
  1501. X            case Sun_R5:
  1502. X            tch = winch(win);
  1503. X            if (isupper(tch))
  1504. X            {
  1505. X                wdelch(win);
  1506. X                winsch(win, tolower(tch));
  1507. X            }
  1508. X            else if (islower(tch))
  1509. X            {
  1510. X                wdelch(win);
  1511. X                winsch(win, toupper(tch));
  1512. X            }
  1513. X            if (x_pos < xend - 1)
  1514. X                my_wmove(++x_pos);
  1515. X            break;
  1516. X            default:
  1517. X            beep();
  1518. X            break;
  1519. X            }
  1520. X        }
  1521. X        }
  1522. X    }
  1523. X    wrefresh(win);
  1524. X    if (xend <= xbeg)
  1525. X        die_curses();
  1526. X    }
  1527. X    win_to_cmd();
  1528. X#ifdef SYSVcurses        /* reset tty */
  1529. X    if (ioctl(0, TCSETA, &tio) != 0)
  1530. X    perror("ioctl");
  1531. X#else
  1532. X    if (ioctl(0, TIOCSETC, &tco) != 0)
  1533. X    perror("ioctl");
  1534. X#endif
  1535. X    NOCBREAKF();
  1536. X    echo();
  1537. X    endwin();
  1538. X    return;            /* finished, execute command */
  1539. X}
  1540. SHAR_EOF
  1541. if test 15455 -ne "`wc -c < 'vi_edit.c'`"
  1542. then
  1543.     echo shar: error transmitting "'vi_edit.c'" '(should have been 15455 characters)'
  1544. fi
  1545. fi # end of overwriting check
  1546. echo shar: extracting "'emacs_edit.c'" '(7558 characters)'
  1547. if test -f 'emacs_edit.c'
  1548. then
  1549.     echo shar: will not over-write existing file "'emacs_edit.c'"
  1550. else
  1551. sed 's/^X//' << \SHAR_EOF > 'emacs_edit.c'
  1552. X/*
  1553. X * This software is Copyright (c) 1991 by Andy Knight
  1554. X *
  1555. X * Permission is hereby granted to copy, distribute or otherwise
  1556. X * use any part of this package as long as you do not try to make
  1557. X * money from it or pretend that you wrote it.  This copyright
  1558. X * notice must be maintained in any copy made.
  1559. X *
  1560. X * Use of this software constitutes acceptance for use in an AS IS
  1561. X * condition. There are NO warranties with regard to this software.
  1562. X * In no event shall the author be liable for any damages whatsoever
  1563. X * arising out of or in connection with the use or performance of this
  1564. X * software.  Any use of this software is at the user's own risk.
  1565. X *
  1566. X * If you make modifications to this software that you feel
  1567. X * increases it usefulness for the rest of the community, please
  1568. X * email the changes, enhancements, bug fixes as well as any and
  1569. X * all ideas to me. This software is going to be maintained and
  1570. X * enhanced as deemed necessary by the community.
  1571. X *
  1572. X * " ... Freely you have recieved, freely give"  <Matthew 10:8> 
  1573. X *
  1574. X *        Andy Knight
  1575. X *        aknight@ourgang.prime.com
  1576. X */
  1577. X
  1578. X#include "config.h"
  1579. X
  1580. Xextern char *hist[], cstr[];
  1581. Xextern int xbeg, cur_cmd, last_hline, pwolfe_getch();
  1582. Xextern int edit_mode, x_pos, savex_pos, xend;
  1583. X
  1584. Xextern void my_wmove(), add_hline(), cmd_to_win(), win_to_cmd();
  1585. Xextern void my_waddstr(), my_winsch(), case_upper();
  1586. Xextern void my_wdelch(), case_lower(), eat_white();
  1587. Xextern SIGTYPE die_curses(), die_normal();
  1588. Xextern WINDOW *win;
  1589. X
  1590. X#ifdef SYSVcurses
  1591. X    extern struct termio tio, tin;
  1592. X#else
  1593. X    extern struct tchars tco, tcn;
  1594. X#endif
  1595. X
  1596. X
  1597. Xedit_cmd()
  1598. X{
  1599. X    int edch, tch, i, tmp_cmd;
  1600. X    fprintf(stdout,"\n");
  1601. X    if(initscr() == ERR)
  1602. X    {
  1603. X    fprintf(stderr, "Curses won't initialize - help!\n");
  1604. X    die_normal();
  1605. X    }
  1606. X    signal(SIGINT,die_curses);      /* die cleanly */
  1607. X    CBREAKF();
  1608. X    noecho();
  1609. X#ifdef SYSVcurses
  1610. X    win = newwin(2,COLS,0,0);
  1611. X#else
  1612. X    clearok(curscr, FALSE);    /* SYSV curses clears it anyway ;-( */
  1613. X    win = newwin(2,COLS,LINES-2,0);
  1614. X#endif
  1615. X
  1616. X    cmd_to_win();
  1617. X    wrefresh(win);
  1618. X
  1619. X#ifdef SYSVcurses        /* disable STOP/START (CTRL-S) */
  1620. X    if(ioctl(0, TCGETA, &tio) != 0)
  1621. X    perror("ioctl");
  1622. X    tin = tio;
  1623. X    tin.c_iflag &= ~IXON;
  1624. X    if(ioctl(0, TCSETA, &tin) != 0)
  1625. X    perror("ioctl");
  1626. X#else
  1627. X    if(ioctl(0, TIOCGETC, &tco) != 0)
  1628. X    perror("ioctl");
  1629. X    tcn = tco;
  1630. X    tcn.t_stopc = -1;
  1631. X    if(ioctl(0, TIOCSETC, &tcn) != 0)
  1632. X    perror("ioctl");
  1633. X#endif
  1634. X    edit_mode = EMACS_MODE;
  1635. X    for (; (edch = pwolfe_getch(win)) != '\n';)
  1636. X    {
  1637. X    switch (edch)
  1638. X    {
  1639. X        case ControlU:
  1640. X        case Sun_R3:
  1641. X        wclear(win);
  1642. X        wrefresh(win);
  1643. X        die_curses();
  1644. X        break;
  1645. X        case ControlW:    /*Delete word backwards*/
  1646. X        case EscapeDEL:
  1647. X        case Sun_R1:
  1648. X        if(x_pos > xbeg)
  1649. X        {
  1650. X            my_wmove(--x_pos);
  1651. X            eat_white(-1,YES);
  1652. X            for(;!(isspace(winch(win))) && (x_pos >= xbeg);)
  1653. X            {
  1654. X            my_wdelch();
  1655. X            if(x_pos == xbeg)
  1656. X                break;
  1657. X            else
  1658. X                my_wmove(--x_pos);
  1659. X            }
  1660. X            if(x_pos > xbeg)
  1661. X                my_wmove(++x_pos);
  1662. X        }
  1663. X        else
  1664. X            beep();
  1665. X        break;
  1666. X        case EscapeB:    /*move back to beginning of previous word*/
  1667. X        case Sun_R4:
  1668. X        if(x_pos > xbeg)
  1669. X        {
  1670. X            my_wmove(--x_pos);
  1671. X            eat_white(-1,NO);
  1672. X            for(;!(isspace(winch(win))) && (x_pos > xbeg);)
  1673. X            {
  1674. X                my_wmove(--x_pos);
  1675. X            }
  1676. X            if(x_pos > xbeg)
  1677. X                my_wmove(++x_pos);
  1678. X        }
  1679. X        else
  1680. X            beep();
  1681. X        break;
  1682. X        case EscapeD:    /*delete forward to beginning of next word*/
  1683. X        if(x_pos < xend)
  1684. X        {
  1685. X            eat_white(1,YES);
  1686. X            for(;!(isspace(winch(win))) && (x_pos < xend);)
  1687. X            {
  1688. X            my_wdelch();
  1689. X            }
  1690. X        }
  1691. X        else
  1692. X            add_hline();
  1693. X        break;
  1694. X        case EscapeF:    /*move forward to beginning of next word*/
  1695. X        case Sun_R6:
  1696. X        if(x_pos < xend)
  1697. X        {
  1698. X            eat_white(1,NO);
  1699. X            for(;!(isspace(winch(win))) && (x_pos < xend);)
  1700. X            {
  1701. X                my_wmove(++x_pos);
  1702. X            }
  1703. X        }
  1704. X        else
  1705. X            beep();
  1706. X        break;
  1707. X        case ControlL:    /* redraw win */
  1708. X        savex_pos = x_pos;
  1709. X        win_to_cmd();
  1710. X        wclear(win);
  1711. X        wrefresh(win);
  1712. X        cmd_to_win();
  1713. X        x_pos = savex_pos;
  1714. X        my_wmove(x_pos);
  1715. X        break;
  1716. X        case BackSpace:
  1717. X        case KEY_LEFT:
  1718. X        case ControlB:
  1719. X        case KEY_BACKSPACE:
  1720. X        case Sun_R10:
  1721. X        if(x_pos > xbeg)
  1722. X            my_wmove(--x_pos);
  1723. X        else
  1724. X            beep();
  1725. X        break;
  1726. X        case EscapeM:    /* move cursor to middle */
  1727. X        case Sun_R11:
  1728. X        x_pos = xbeg + (xend-xbeg)/2;
  1729. X        my_wmove(x_pos);
  1730. X        break;
  1731. X        case ControlF:
  1732. X        case KEY_RIGHT:
  1733. X        case Sun_R12:
  1734. X        if(x_pos < xend)
  1735. X            my_wmove(++x_pos);
  1736. X        else
  1737. X            beep();
  1738. X        break;
  1739. X        case KEY_UP:    /* move upward in history list */
  1740. X        case ControlP:
  1741. X        case Sun_R8:
  1742. X        if(cur_cmd > 0)
  1743. X        {
  1744. X            --cur_cmd;
  1745. X            strcpy(cstr, hist[cur_cmd]);
  1746. X            wclear(win);
  1747. X            cmd_to_win();
  1748. X            my_wmove(x_pos);
  1749. X        }
  1750. X        else
  1751. X            beep();
  1752. X        break;
  1753. X        case KEY_DOWN:    /* move downward in history list */
  1754. X        case ControlN:
  1755. X        case Sun_R14:
  1756. X        if(cur_cmd < last_hline)
  1757. X        {
  1758. X            ++cur_cmd;
  1759. X            strcpy(cstr, hist[cur_cmd]);
  1760. X            wclear(win);
  1761. X            cmd_to_win();
  1762. X            my_wmove(x_pos);
  1763. X        }
  1764. X        else
  1765. X            beep();
  1766. X        break;
  1767. X        case ControlR:    /*search history list backwards*/
  1768. X        if((tmp_cmd = index_cmd(cur_cmd - 1,-1)) != cur_cmd)
  1769. X        {
  1770. X            cur_cmd = tmp_cmd;
  1771. X            strcpy(cstr, hist[cur_cmd]);
  1772. X            wclear(win);
  1773. X            cmd_to_win();
  1774. X            my_wmove(x_pos);
  1775. X        }
  1776. X        else
  1777. X            beep();
  1778. X        break;
  1779. X        case ControlS:    /*search history list forwards*/
  1780. X        if((tmp_cmd = index_cmd(cur_cmd + 1,1)) != cur_cmd)
  1781. X        {
  1782. X            cur_cmd = tmp_cmd;
  1783. X            strcpy(cstr, hist[cur_cmd]);
  1784. X            wclear(win);
  1785. X            cmd_to_win();
  1786. X            my_wmove(x_pos);
  1787. X        }
  1788. X        else
  1789. X            beep();
  1790. X        break;
  1791. X        case ControlA:
  1792. X        case Sun_R7:
  1793. X        my_wmove(xbeg);
  1794. X        x_pos = xbeg;
  1795. X        break;
  1796. X        case ControlE:
  1797. X        case Sun_R13:
  1798. X        case Sun_R9:
  1799. X        my_wmove(xend);
  1800. X        x_pos = xend;
  1801. X        break;
  1802. X        case ControlK:    /*delete to end of line*/
  1803. X        if(x_pos < xend)
  1804. X        {
  1805. X            for(i = xend; i > x_pos; i--)
  1806. X            {
  1807. X            my_wdelch();
  1808. X            }
  1809. X        }
  1810. X        else
  1811. X                    add_hline();
  1812. X        break;
  1813. X        case Delete:    /*delete character before cursor*/
  1814. X        if(x_pos > xbeg)
  1815. X        {
  1816. X            my_wmove(--x_pos);
  1817. X            my_wdelch();
  1818. X        }
  1819. X        else
  1820. X            beep();
  1821. X        break;
  1822. X        case ControlD:    /*delete current character*/
  1823. X        if(x_pos < xend)
  1824. X        {
  1825. X            my_wdelch();
  1826. X        }
  1827. X        else
  1828. X            add_hline();
  1829. X        break;
  1830. X        case EscapeL:    /*lower case whole command*/
  1831. X        case Sun_R2:
  1832. X        savex_pos = x_pos;
  1833. X        win_to_cmd();
  1834. X        case_lower();
  1835. X        cmd_to_win();
  1836. X        x_pos = savex_pos;
  1837. X        my_wmove(x_pos);
  1838. X        break;
  1839. X        case EscapeU:    /*upper case whole command*/
  1840. X        savex_pos = x_pos;
  1841. X        win_to_cmd();
  1842. X        case_upper();
  1843. X        cmd_to_win();
  1844. X        x_pos = savex_pos;
  1845. X        my_wmove(x_pos);
  1846. X        break;
  1847. X        case EscapeC:    /* toggle case of current character */
  1848. X        case Sun_R5:
  1849. X        tch = winch(win);
  1850. X        if(isupper(tch))
  1851. X        {
  1852. X            wdelch(win);
  1853. X            winsch(win,tolower(tch));
  1854. X        }
  1855. X        else if(islower(tch))
  1856. X        {
  1857. X            wdelch(win);
  1858. X            winsch(win,toupper(tch));
  1859. X        }
  1860. X        if(x_pos < xend)
  1861. X            my_wmove(++x_pos);
  1862. X        break;
  1863. X        case ControlT:    /* transpose characters */
  1864. X        if(x_pos > xbeg && x_pos != COLS)
  1865. X        {
  1866. X            if(x_pos == xend)
  1867. X                my_wmove(--x_pos);
  1868. X            my_wmove(--x_pos);
  1869. X            tch = winch(win);
  1870. X            wdelch(win);
  1871. X            my_wmove(++x_pos);
  1872. X            winsch(win,tch);
  1873. X            my_wmove(++x_pos);
  1874. X        }
  1875. X        else
  1876. X            beep();
  1877. X        break;
  1878. X        default:        /* insert character */
  1879. X        if(isprint(edch))
  1880. X        {
  1881. X            my_winsch(edch);
  1882. X        }
  1883. X        else
  1884. X            beep();
  1885. X        break;
  1886. X    }
  1887. X    wrefresh(win);
  1888. X    if (xend == xbeg)
  1889. X        die_curses();
  1890. X    }
  1891. X    win_to_cmd();
  1892. X#ifdef SYSVcurses    /* reset tty */
  1893. X    if(ioctl(0, TCSETA, &tio) != 0)
  1894. X    perror("ioctl");
  1895. X#else
  1896. X    if(ioctl(0, TIOCSETC, &tco) != 0)
  1897. X    perror("ioctl");
  1898. X#endif
  1899. X    NOCBREAKF();
  1900. X    echo();
  1901. X    endwin();
  1902. X    return;    /* finished, execute command */
  1903. X}
  1904. SHAR_EOF
  1905. if test 7558 -ne "`wc -c < 'emacs_edit.c'`"
  1906. then
  1907.     echo shar: error transmitting "'emacs_edit.c'" '(should have been 7558 characters)'
  1908. fi
  1909. fi # end of overwriting check
  1910. echo shar: extracting "'getch.c'" '(3131 characters)'
  1911. if test -f 'getch.c'
  1912. then
  1913.     echo shar: will not over-write existing file "'getch.c'"
  1914. else
  1915. sed 's/^X//' << \SHAR_EOF > 'getch.c'
  1916. X
  1917. X/*
  1918. X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe.
  1919. X *
  1920. X * Permission is hereby granted to copy, distribute or otherwise
  1921. X * use any part of this package as long as you do not try to make
  1922. X * money from it or pretend that you wrote it.  This copyright
  1923. X * notice must be maintained in any copy made.
  1924. X *
  1925. X * Use of this software constitutes acceptance for use in an AS IS
  1926. X * condition. There are NO warranties with regard to this software.
  1927. X * In no event shall the author be liable for any damages whatsoever
  1928. X * arising out of or in connection with the use or performance of this
  1929. X * software.  Any use of this software is at the user's own risk.
  1930. X *
  1931. X * If you make modifications to this software that you feel
  1932. X * increases it usefulness for the rest of the community, please
  1933. X * email the changes, enhancements, bug fixes as well as any and
  1934. X * all ideas to me. This software is going to be maintained and
  1935. X * enhanced as deemed necessary by the community.
  1936. X *
  1937. X *              Patrick J. Wolfe
  1938. X *              uunet!uiucuxc!kailand!pwolfe
  1939. X *              pwolfe@kailand.kai.com
  1940. X */
  1941. X
  1942. X/*****************************************************************
  1943. X * Modifications made by aknight to support emacs escape functions,
  1944. X * Sun R function keys and vi escape, wiped out un-needed stuff
  1945. X * for vt120, vt220
  1946. X *****************************************************************/
  1947. X
  1948. X#include "config.h"
  1949. X
  1950. X#define NORMAL    100
  1951. X#define ESCAPE    200
  1952. X#define FKEY    300
  1953. X
  1954. Xextern int      edit_mode;
  1955. X
  1956. X
  1957. Xint
  1958. Xpwolfe_getch(winptr)
  1959. X    WINDOW         *winptr;
  1960. X{
  1961. X    char            c;
  1962. X    int             state = NORMAL;
  1963. X    int             fkeycount = 0;
  1964. X
  1965. X    while (1)
  1966. X    {
  1967. X    c = wgetch(winptr);    /* call the real getch() */
  1968. X    switch (state)
  1969. X    {
  1970. X
  1971. X    case FKEY:
  1972. X        switch (c)
  1973. X        {
  1974. X
  1975. X        /* numeric function keys */
  1976. X        case '0':
  1977. X        case '1':
  1978. X        case '2':
  1979. X        case '3':
  1980. X        case '4':
  1981. X        case '5':
  1982. X        case '6':
  1983. X        case '7':
  1984. X        case '8':
  1985. X        case '9':
  1986. X        fkeycount = (fkeycount * 10) + (c - '0');
  1987. X        break;
  1988. X
  1989. X/* lines deleted, aknight*/
  1990. X
  1991. X        case 'A':
  1992. X        return KEY_UP;
  1993. X        case 'B':
  1994. X        return KEY_DOWN;
  1995. X        case 'C':
  1996. X        return KEY_RIGHT;
  1997. X        case 'D':
  1998. X        return KEY_LEFT;
  1999. X
  2000. X/* added by aknight, R1 - R15 keys on Sun*/
  2001. X        case 'z':
  2002. X        return fkeycount + 1000;
  2003. X
  2004. X        default:
  2005. X        beep();
  2006. X        state = NORMAL;
  2007. X        }
  2008. X        break;
  2009. X
  2010. X    case ESCAPE:
  2011. X        switch (c)
  2012. X        {
  2013. X        case 'O':
  2014. X        case '[':
  2015. X        state = FKEY;
  2016. X        fkeycount = 0;
  2017. X        break;
  2018. X/* added by aknight, Escape - key functions */
  2019. X        case 'f':
  2020. X        return EscapeF;
  2021. X        case 'b':
  2022. X        return EscapeB;
  2023. X        case 'd':
  2024. X        return EscapeD;
  2025. X        case 'c':
  2026. X        return EscapeC;
  2027. X        case 'l':
  2028. X        return EscapeL;
  2029. X        case 'u':
  2030. X        return EscapeU;
  2031. X        case 'm':
  2032. X        return EscapeM;
  2033. X        case Delete:
  2034. X        return EscapeDEL;
  2035. X        case Escape:
  2036. X        state = ESCAPE;
  2037. X        break;
  2038. X
  2039. X        default:
  2040. X        state = NORMAL;
  2041. X        beep();
  2042. X        }
  2043. X        break;
  2044. X
  2045. X    default:
  2046. X        switch (c)
  2047. X        {
  2048. X        case Escape:
  2049. X        state = ESCAPE;
  2050. X/* added by aknight */
  2051. X        if (edit_mode == VI_INS_MODE || edit_mode == VI_R_MODE)
  2052. X            return Escape;
  2053. X        break;
  2054. X
  2055. X        case CSI:
  2056. X        state = FKEY;
  2057. X        fkeycount = 0;
  2058. X        break;
  2059. X
  2060. X        default:
  2061. X        return (c);
  2062. X        }
  2063. X    }
  2064. X    }
  2065. X}
  2066. SHAR_EOF
  2067. if test 3131 -ne "`wc -c < 'getch.c'`"
  2068. then
  2069.     echo shar: error transmitting "'getch.c'" '(should have been 3131 characters)'
  2070. fi
  2071. fi # end of overwriting check
  2072. echo shar: extracting "'getch.h'" '(2932 characters)'
  2073. if test -f 'getch.h'
  2074. then
  2075.     echo shar: will not over-write existing file "'getch.h'"
  2076. else
  2077. sed 's/^X//' << \SHAR_EOF > 'getch.h'
  2078. X
  2079. X/*
  2080. X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe.
  2081. X *
  2082. X * Permission is hereby granted to copy, distribute or otherwise 
  2083. X * use any part of this package as long as you do not try to make 
  2084. X * money from it or pretend that you wrote it.  This copyright 
  2085. X * notice must be maintained in any copy made.
  2086. X *
  2087. X * Use of this software constitutes acceptance for use in an AS IS 
  2088. X * condition. There are NO warranties with regard to this software.  
  2089. X * In no event shall the author be liable for any damages whatsoever 
  2090. X * arising out of or in connection with the use or performance of this 
  2091. X * software.  Any use of this software is at the user's own risk.
  2092. X *
  2093. X * If you make modifications to this software that you feel 
  2094. X * increases it usefulness for the rest of the community, please 
  2095. X * email the changes, enhancements, bug fixes as well as any and 
  2096. X * all ideas to me. This software is going to be maintained and 
  2097. X * enhanced as deemed necessary by the community.
  2098. X *              
  2099. X *              Patrick J. Wolfe
  2100. X *              uunet!uiucuxc!kailand!pwolfe
  2101. X *              pwolfe@kailand.kai.com
  2102. X */
  2103. X
  2104. X/*************************************************************
  2105. X * Modifications made by aknight to add definitions for escape
  2106. X * functions and Sun R function keys, also wiped out sections
  2107. X * for SYSVcurses, VT120, VT220
  2108. X ************************************************************/
  2109. X#ifndef SYSVcurses
  2110. X/* System V curses key names and codes returned by getch */
  2111. X#define KEY_DOWN        0402
  2112. X#define KEY_UP          0403
  2113. X#define KEY_LEFT        0404
  2114. X#define KEY_RIGHT       0405
  2115. X#define KEY_BACKSPACE   0407
  2116. X#endif /* NOT SYSVcurses */
  2117. X
  2118. X/* ascii control codes */
  2119. X#define ControlA    001
  2120. X#define ControlB    002
  2121. X#define ControlC    003
  2122. X#define ControlD    004
  2123. X#define ControlE    005
  2124. X#define ControlF    006
  2125. X#define ControlG    007
  2126. X#define ControlH    010
  2127. X#define BackSpace    010
  2128. X#define ControlI    011
  2129. X#define Tab        011
  2130. X#define ControlJ    012
  2131. X#define LineFeed    012
  2132. X#define ControlK    013
  2133. X#define ControlL    014
  2134. X#define ControlM    015
  2135. X#define Return        015
  2136. X#define ControlN    016
  2137. X#define ControlO    017
  2138. X#define ControlP    020
  2139. X#define ControlQ    021
  2140. X#define ControlR    022
  2141. X#define ControlS    023
  2142. X#define ControlT    024
  2143. X#define ControlU    025
  2144. X#define ControlV    026
  2145. X#define ControlW    027
  2146. X#define ControlX    030
  2147. X#define ControlY    031
  2148. X#define ControlZ    032
  2149. X#define Escape        033
  2150. X#define Control[    033
  2151. X#define Delete        0177
  2152. X#define Del        0177
  2153. X#define CSI        0233
  2154. X
  2155. X/* added by aknight */
  2156. X
  2157. X#define EscapeD        1001
  2158. X#define EscapeF        1002
  2159. X#define EscapeB        1003
  2160. X#define EscapeDEL    1004
  2161. X#define EscapeM        1005
  2162. X#define EscapeC        1006
  2163. X#define EscapeU        1007
  2164. X#define EscapeL        1008
  2165. X
  2166. X#define Sun_R1        1208
  2167. X#define Sun_R2        1209
  2168. X#define Sun_R3        1210
  2169. X#define Sun_R4        1211
  2170. X#define Sun_R5        1212
  2171. X#define Sun_R6        1213
  2172. X#define Sun_R7        1214
  2173. X#define Sun_R8        1215
  2174. X#define Sun_R9        1216
  2175. X#define Sun_R10        1217
  2176. X#define Sun_R11        1218
  2177. X#define Sun_R12        1219
  2178. X#define Sun_R13        1220
  2179. X#define Sun_R14        1221
  2180. X#define Sun_R15        1222
  2181. SHAR_EOF
  2182. if test 2932 -ne "`wc -c < 'getch.h'`"
  2183. then
  2184.     echo shar: error transmitting "'getch.h'" '(should have been 2932 characters)'
  2185. fi
  2186. fi # end of overwriting check
  2187. echo shar: extracting "'config.h'" '(2003 characters)'
  2188. if test -f 'config.h'
  2189. then
  2190.     echo shar: will not over-write existing file "'config.h'"
  2191. else
  2192. sed 's/^X//' << \SHAR_EOF > 'config.h'
  2193. X/*
  2194. X *        Configuration file for mced
  2195. X */
  2196. X
  2197. X#define PROMPT "%McEd% "    /* change to whatever you like, just make
  2198. X                 * sure it is enclosed with double quotes */
  2199. X
  2200. X#define CBREAKF crmode        /* change to cbreak if your system does not
  2201. X                 * have curses compatibility routine "crmode" */
  2202. X
  2203. X#define NOCBREAKF nocrmode    /* change to nocbreak if your system does not
  2204. X                 * have curses compatibility routine
  2205. X                 * "nocrmode" */
  2206. X
  2207. X
  2208. X#define MIN_CMD_LEN 5        /* Min number of characters in command line
  2209. X                 * to be considered worthy */
  2210. X
  2211. X#define MAX_CH 300        /* Max number of characters in command line */
  2212. X
  2213. X#define MAX_H_READ 250        /* Max number of history lines possible to
  2214. X                 * read */
  2215. X
  2216. X#define MAX_W_SAVED 50        /* Max word length to save on edits */
  2217. X
  2218. X
  2219. X#define BUFSIZE 4096        /* buffer size for file read, reads only once
  2220. X                 * so must be large enough for whole history file. 
  2221. X                 * (If you need more than 4096
  2222. X                 * you should join packrats anonymous!! :-) */
  2223. X
  2224. X/*
  2225. X * the following is from config.h for scan by Patrick J. Wolfe:
  2226. X */
  2227. X
  2228. X/*
  2229. X *      Define "SIGTYPE" to the type of the value returned by the "signal"
  2230. X *      system call.  On BSD 4.2 systems, it's "void".  On BSD 4.3 and SVR3
  2231. X *      systems, it's "int".
  2232. X *
  2233. X *    Define "SYSVcurses" if your system only has System V curses.
  2234. X */
  2235. X
  2236. X#define SIGTYPE int
  2237. X
  2238. X#define beep()  fprintf (stderr, "\007");
  2239. X
  2240. X#define YES 1
  2241. X#define NO  0
  2242. X
  2243. X#define MIN(a, b) (((a) < (b)) ? (a) : (b))
  2244. X
  2245. X#define EMACS_MODE 1        /* dont edit these, see the Makefile */
  2246. X#define VI_INS_MODE 2        /* to select emacs mode or vi mode */
  2247. X
  2248. X#define VI_NINS_MODE 3
  2249. X#define VI_c_MODE 4
  2250. X#define VI_d_MODE 5
  2251. X#define VI_r_MODE 6
  2252. X#define VI_R_MODE 7
  2253. X#define NO_BEG_INS 8
  2254. X
  2255. X
  2256. X#include "getch.h"
  2257. X
  2258. X/* {string,strings}.h file definitions */
  2259. Xextern char    *strcpy(), *strncpy(), *strcat(), *strncat();
  2260. Xextern int      strcmp(), strncmp(), strlen();
  2261. X
  2262. X#include <stdio.h>
  2263. X#include <ctype.h>
  2264. X#include <signal.h>
  2265. X#include <curses.h>
  2266. X#include <errno.h>
  2267. X
  2268. X#ifdef SYSVcurses
  2269. X#include <termio.h>
  2270. X#else
  2271. X#include <sys/ioctl.h>
  2272. X#endif
  2273. SHAR_EOF
  2274. if test 2003 -ne "`wc -c < 'config.h'`"
  2275. then
  2276.     echo shar: error transmitting "'config.h'" '(should have been 2003 characters)'
  2277. fi
  2278. fi # end of overwriting check
  2279. #    End of shell archive
  2280. exit 0
  2281.  
  2282. exit 0 # Just in case...
  2283. -- 
  2284. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2285. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2286. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2287. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2288.